package com.sk.mybatis.tools;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.StopWatch;

import java.io.*;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;


public class Generate {
    static String basePath = "D:\\generate\\";
    static String basePackage = "cn.zm518.mc2";
    //1:模块包名(一个功能一个模块)
    static String modular = "exposition";
    //前缀,不填不去,填了自动去掉前缀
    static String prefix = "";

    public static void main(String[] args) throws IOException, TemplateException, SQLException, ClassNotFoundException {

        String config = FileUtils.readFileToString(new File("info.json"), "utf-8");
        JSONObject object = JSON.parseObject(config);
        basePath = object.getString("basePath") + "\\";
        basePackage = object.getString("basePackage");
        modular = object.getString("modular");
        prefix = object.getString("prefix");


        StopWatch watch = new StopWatch();
        if (basePath.length() < 10) {
            System.out.println("根目录太短位置防止错误 删除,根目录需要>10");
            return;
        }
        FileUtils.deleteDirectory(new File(basePath));
        watch.start();
        basePath = basePath + modular + "/";
        String tablesNames[] = object.getJSONArray("tablesNames").toArray(new String[object.getJSONArray("tablesNames").size()]);
        for (String tablesName : tablesNames) {
            Generate g = new Generate();
            g.generate(tablesName);
        }
        watch.stop();
        System.out.println("生成成功:" + watch.getTime());
        Runtime.getRuntime().exec(
                "rundll32 SHELL32.DLL,ShellExec_RunDLL " +
                        "Explorer.exe /select," + "D:\\generate\\" + modular);
    }

    /**
     * 使用模板生成
     *
     * @param property
     * @throws IOException
     * @throws FileNotFoundException
     * @throws TemplateException
     */
    private static void generateCode(BeanProperty property) throws IOException, TemplateException {
        Configuration cfg = initFreemarkerConfig();
        //生成bean
        process(property, cfg, "entity.ftl", ".java", "entity");
        // controller
        process(property, cfg, "controller.ftl", "Controller.java", "controller");
        // service
        process(property, cfg, "service.ftl", "Service.java", "service");
        //serviceImpl
        process(property, cfg, "serviceImpl.ftl", "ServiceImpl.java", "service" + File.separator + "impl");
        //mapper
        process(property, cfg, "mapper.ftl", "Mapper.java", "mapper");
        // mapper xml1
        process(property, cfg, "mapperXml.ftl", "Mapper.xml", "mapper");
        // list
        process(property, cfg, "page_list.ftl", ".vue", "page");
        //add
        process(property, cfg, "page_add.ftl", ".vue", "page");
        //edit
        process(property, cfg, "page_edit.ftl", ".vue", "page");
        //detail
        process(property, cfg, "page_detail.ftl", ".vue", "page");
        // 路由,page ,按钮
        process(property, cfg, "page_config.ftl", ".vue", "page");
    }

    // 调用freemarker生成
    private static void process(BeanProperty property, Configuration cfg, String template, String classExtends, String path) throws IOException, TemplateException {
        System.out.println(template);
        Template bean = cfg.getTemplate(template);
        File file = new File(basePath + File.separator + path);
        if (!file.exists()) {
            file.mkdirs();
        }
        if ("page".equals(path)) {
            file = new File(basePath + File.separator + path + File.separator + property.getTableName());
            if (!file.exists()) {
                file.mkdirs();
            }
            Writer out = new OutputStreamWriter(
                    new FileOutputStream(basePath + File.separator + path + File.separator + property.getTableName() + File.separator + template.replace("page_", "").replace(".ftl", "") + ".vue"));
            bean.process(property, out);
            out.close();
            return;
        }
        Writer out = new OutputStreamWriter(
                new FileOutputStream(basePath + File.separator + path + File.separator + property.getClassName() + classExtends));
        bean.process(property, out);
        out.close();
    }

    // 初始化配置信息
    private static Configuration initFreemarkerConfig() throws IOException {
        Configuration cfg = new Configuration();
        cfg.setEncoding(Locale.CHINA, "UTF-8");
        cfg.setDirectoryForTemplateLoading(new File("template"));
        cfg.setObjectWrapper(new DefaultObjectWrapper());
        return cfg;
    }

    private void generate(String tableName) throws SQLException, ClassNotFoundException, IOException, TemplateException {
        MysqlInfoUtil mysql = new MysqlInfoUtil();
        List<Column> columnList = mysql.getColumnMappingInfo(tableName);
        BeanProperty property = new BeanProperty();
        property.setPkName(basePackage + "." + modular);
        property.setTableName(tableName);
        String className = tableName;
        if (StringUtils.isNotBlank(prefix) && tableName.startsWith(prefix)) {
            className = tableName.replace(prefix, "");
        }
        property.setClassName(mysql.underLineToCamelCase(className));
        List<Filed> filedNames = new ArrayList<>();
        for (Column column : columnList) {
            String fiName = mysql.underLineToCamelCase(column.getColumnName());
            String s = fiName.substring(0, 1).toLowerCase() + fiName.substring(1);
            filedNames.add(new Filed(column.getRemarks(), s, column.getType(), column.getColumnName()));
        }
        property.setFiledNames(filedNames);
        generateCode(property);
    }
}
